/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package pl.mwas.proteana.annotations;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Objects;
import pl.mwas.proteana.geneontology.GOTerm;
import pl.mwas.proteana.geneontology.GOTermDb;

/**
 *
 * @author mateusz.was
 */
public class GOAnnotation {
    
    private String db;
    private String dbId;
    private String dbSymbol;
    private ArrayList<String> qualifiers;
    private String goId;
    private ArrayList<String> dbReference;
    private String evidenceCode;
    private ArrayList<String> withOrFrom;
    private String aspect;
    private String dbName;
    private ArrayList<String> dbSynonym;
    private String dbType;
    private ArrayList<String> taxon;
    private String date;
    private String assignedBy;
    private ArrayList<String> annotationExtension;
    private String geneProduct;
    
    private GOTerm goTerm;

    public GOAnnotation(String db, String dbId, String dbSymbol,
            String qualifiers, String goId,
            String dbReference, String evidenceCode,
            String withOrFrom, String aspect, String dbName,
            String dbSynonym, String dbType,
            String taxon, String date, String assignedBy,
            String annotationExtension, String geneProduct) {
        this.db = db;
        this.dbId = dbId;
        this.dbSymbol = dbSymbol;
        this.qualifiers = parseMultiplePropertyString(qualifiers);
        this.goId = goId;
        this.dbReference = parseMultiplePropertyString(dbReference);
        this.evidenceCode = evidenceCode;
        this.withOrFrom = parseMultiplePropertyString(withOrFrom);
        this.aspect = aspect;
        this.dbName = dbName;
        this.dbSynonym = parseMultiplePropertyString(dbSynonym);
        this.dbType = dbType;
        this.taxon = parseMultiplePropertyString(taxon);
        this.date = date;
        this.assignedBy = assignedBy;
        this.annotationExtension = parseMultiplePropertyString(annotationExtension);
        this.geneProduct = geneProduct;
    }
    
    public GOAnnotation(String line) {
        this(line.split("\t", -1));        // -1 states for: used as much as you can, also at end of string
    }
    
    public GOAnnotation(String[] splited) {
        this(splited[0], splited[1], splited[2], splited[3], splited[4], splited[5], splited[6], splited[7], splited[8], splited[9], splited[10], splited[11], splited[12], splited[13], splited[14], splited[15], splited[16]);
    }
    
    private ArrayList<String> parseMultiplePropertyString(String toParse) {
        ArrayList<String> target = new ArrayList<>();
        if (!toParse.equals("")) {
            String[] propertyList = toParse.split("\\|", -1);
            if (propertyList.length == 0) {
                target = new ArrayList<>();
            } else {
                target = new ArrayList<>(Arrays.asList(propertyList));
            }
        }
        return target;
    }
    
    public void linkToGOTerm(GOTermDb goDb) {
        this.goTerm = goDb.getTerm(this.goId);
    }

    public GOTerm getGoTerm() {
        return goTerm;
    }

    @Override
    public String toString() {
        return "GOAnnotation{" + "\n db=" + db + "\n dbId=" + dbId + "\n dbSymbol=" + dbSymbol + "\n qualifiers=" + qualifiers + "\n goId=" + goId + "\n dbReference=" + dbReference + "\n evidenceCode=" + evidenceCode + "\n withOrFrom=" + withOrFrom + "\n aspect=" + aspect + "\n dbName=" + dbName + "\n dbSynonym=" + dbSynonym + "\n dbType=" + dbType + "\n taxon=" + taxon + "\n date=" + date + "\n assignedBy=" + assignedBy + "\n annotationExtension=" + annotationExtension + "\n geneProduct=" + geneProduct + "\n }";
    }

    public String getDb() {
        return db;
    }

    public String getDbId() {
        return dbId;
    }

    public String getGoId() {
        return goId;
    }

    public String getDbName() {
        return dbName;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 67 * hash + Objects.hashCode(this.db);
        hash = 67 * hash + Objects.hashCode(this.dbId);
        hash = 67 * hash + Objects.hashCode(this.dbSymbol);
        hash = 67 * hash + Objects.hashCode(this.qualifiers);
        hash = 67 * hash + Objects.hashCode(this.goId);
        hash = 67 * hash + Objects.hashCode(this.dbReference);
        hash = 67 * hash + Objects.hashCode(this.evidenceCode);
        hash = 67 * hash + Objects.hashCode(this.withOrFrom);
        hash = 67 * hash + Objects.hashCode(this.aspect);
        hash = 67 * hash + Objects.hashCode(this.dbName);
        hash = 67 * hash + Objects.hashCode(this.dbSynonym);
        hash = 67 * hash + Objects.hashCode(this.dbType);
        hash = 67 * hash + Objects.hashCode(this.taxon);
        hash = 67 * hash + Objects.hashCode(this.date);
        hash = 67 * hash + Objects.hashCode(this.assignedBy);
        hash = 67 * hash + Objects.hashCode(this.annotationExtension);
        hash = 67 * hash + Objects.hashCode(this.geneProduct);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final GOAnnotation other = (GOAnnotation) obj;
        if (!Objects.equals(this.db, other.db)) {
            return false;
        }
        if (!Objects.equals(this.dbId, other.dbId)) {
            return false;
        }
        if (!Objects.equals(this.dbSymbol, other.dbSymbol)) {
            return false;
        }
        if (!Objects.equals(this.qualifiers, other.qualifiers)) {
            return false;
        }
        if (!Objects.equals(this.goId, other.goId)) {
            return false;
        }
        if (!Objects.equals(this.dbReference, other.dbReference)) {
            return false;
        }
        if (!Objects.equals(this.evidenceCode, other.evidenceCode)) {
            return false;
        }
        if (!Objects.equals(this.withOrFrom, other.withOrFrom)) {
            return false;
        }
        if (!Objects.equals(this.aspect, other.aspect)) {
            return false;
        }
        if (!Objects.equals(this.dbName, other.dbName)) {
            return false;
        }
        if (!Objects.equals(this.dbSynonym, other.dbSynonym)) {
            return false;
        }
        if (!Objects.equals(this.dbType, other.dbType)) {
            return false;
        }
        if (!Objects.equals(this.taxon, other.taxon)) {
            return false;
        }
        if (!Objects.equals(this.date, other.date)) {
            return false;
        }
        if (!Objects.equals(this.assignedBy, other.assignedBy)) {
            return false;
        }
        if (!Objects.equals(this.annotationExtension, other.annotationExtension)) {
            return false;
        }
        if (!Objects.equals(this.geneProduct, other.geneProduct)) {
            return false;
        }
        return true;
    }
    
    
}
